package edu.uba.fcen.estimacion.cubrimiento;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import edu.uba.fcen.estimacion.word.selection.Pair;
import edu.uba.fcen.estimacion.word.selection.WriterResult;
import edu.uba.fcen.estimacion.word.selection.filter.FilterWords;
import edu.uba.fcen.estimacion.word.selection.filter.NormalLineByLine;

/**
 *	Esta clase normaliza la cantidad de palabras de un conjunto de datos.
 *	La normalizacion se lleva adelante por cada palabra de la siguiente manera:
 *		# apariciones de una palabra
 *		----------------------------
 *		Suma de # apariciones de todas las palabras  
 */
public class NormalizationAmountOfWords {

	static Map<String, Double> map = new HashMap<String, Double>();
	
	public static void main(String[] args) {
		String pathDataSet = args[0];
		String pathOut = args[1];
		double totalNumberOcurrence = sumAllOcurrence(pathDataSet);
		normalizeWords(totalNumberOcurrence, pathDataSet);
		writeResult(pathOut);
	}

	private static void writeResult(String pathOut) {
		WriterResult writer = new WriterResult("normalizedWords.txt", pathOut);
		for (Pair<String, Double> pair : getSortedList()) {
			DecimalFormat df = new DecimalFormat("###.########################");
			writer.writeWithEnter(pair.getX() + "\t\t\t" + df.format(pair.getY()));
		}
	}

	private static void normalizeWords(double totalNumberOcurrence,
			String pathDataSet) {
		FilterWords fw = new NormalLineByLine(pathDataSet);
		String line;
		double ocurrenceOfWord = 0d;
		while ((line=fw.readLine())!=null) {
			String[] split = line.split("\t\t\t");
			ocurrenceOfWord = Double.valueOf(split[1]);
			map.put(split[0], ocurrenceOfWord/totalNumberOcurrence);
		}
	}

	private static double sumAllOcurrence(String pathDataSet) {
		FilterWords fw = new NormalLineByLine(pathDataSet);
		String line;
		double sumAllOcurrence = 0d;
		while ((line=fw.readLine())!=null) {
			String[] split = line.split("\t\t\t");
			sumAllOcurrence += Double.valueOf(split[1]);
		}
		return sumAllOcurrence;
	}
	
	private static List<Pair<String, Double>> getSortedList() {
		List<Pair<String, Double>> sortedList = new ArrayList<Pair<String,Double>>(map.size());
		
		for (String key : map.keySet()) {
			sortedList.add(new Pair<String, Double>(key, map.get(key)));
		}
		Collections.sort(sortedList, new Comparator<Pair<String,Double>>() {

			@Override
			public int compare(Pair<String,Double> o1, Pair<String,Double> o2) {
				return o2.getY().compareTo(o1.getY());
			}
		});
		return sortedList;
	}

}
